#include "gui/util/GUIEvent.h"
#include "gui/GUIApplication.h"
#include "util/logger/LoggerManager.h"
#include <sstream>

namespace gui {

//GUIApplication::GUIApplication(GUIMap* guiMap, double xScale, double yScale) {
GUIApplication::GUIApplication(GUIMap* guiMap, int viewportX, int viewportY, int viewportScrollSpeed,
		int screenW, int screenH, int screenBPP, std::string screenCaption, bool fullscreen) {

	stringstream texto;	texto.str("");
	texto << "Creando GUIApplication con valores:"
		<< "\n\t  viewportX [metros] = " << viewportX
		<< "\n\t  viewportY [metros] = " << viewportY
		<< "\n\t  viewportScrollSpeed [px] = " << viewportScrollSpeed
		<< "\n\t  screenWidth [px] = " << screenW
		<< "\n\t  screenHeight [px] = " << screenH
		<< "\n\t  screenBPP = " << screenBPP
		<< "\n\t  screenCaption = " << screenCaption
		<< "\n\t  fullscreen? = " << fullscreen;
	this->logger()->info(texto.str());

	// se crea el motor de graficos
	this->engine = new GUIEngine(
			screenW,screenH,screenBPP,screenCaption,fullscreen,
			guiMap->getLeftLimit(), guiMap->getTopLimit()
	);

	// Se necesita transformar estos valores a "pixel standard"
	viewportX = gui::toPixels(viewportX);
	viewportY = gui::toPixels(viewportY);

	texto.str("");
	texto << "Convirtiendo valores del viewport a std pixel..."
		<< "\n\t  viewportX [px std] = " << viewportX
		<< "\n\t  viewportY [px std] = " << viewportY;
	this->logger()->info(texto.str());

	// se crea el viewport, porcion visible mapa
	// pasandole como parametros de ancho y alto el tama�o de la porcion de mapa que se dibujara en el, en pixeles standard
	this->viewport = new Viewport(guiMap,viewportX,viewportY,viewportScrollSpeed);
	// vieja forma de crear al viewport: this->viewport = new Viewport(guiMap,screenW,screenH,viewportScrollSpeed);

	// Calculo la escala deseada
	double xScale = (double) screenW / viewportX;
	double yScale = (double) screenH / viewportY;

	texto.str("");
	texto << "GUIEngine utilizara las siguientes escalas..."
		<< "\n\t  xScale = " << xScale << "\n\t  yScale = " << yScale;
	this->logger()->info(texto.str());

	this->engine->setScale(xScale, yScale);
}

GUIApplication::~GUIApplication() {
	delete this->engine;
	delete this->viewport;
}

void GUIApplication::launch() {
	if (!this->engine->start(
			this->viewport->getGUIMap()->getTotalHeight(), this->viewport->getGUIMap()->getTotalWidth(),
			app::ApplicationConfig::getBooleanProperty("showSplashScreen"))) {
		logger()->error("No se pudo inicializar el motor grafico.");
		return;
	}
	this->engine->drawGUIObjects(this->viewport->getObjectsToDraw(), true);
	ViewportMove horizontalMovement = Ini;
	ViewportMove verticalMovement = Ini;
	bool appRunning = true;
	GUIEvent event;
	while (appRunning) {
		if (this->engine->pollEvent(&event)) {
			appRunning = !((event.getType() == Quit) || (event.getKey()	== Escape));
		}
		if (this->engine->getKeyState(KeyLeft)) {
			horizontalMovement = MoveLeft;
		}
		if (this->engine->getKeyState(KeyRight)) {
			horizontalMovement = MoveRight;
		}
		if (this->engine->getKeyState(KeyUp)) {
			verticalMovement = MoveUp;
		}
		if (this->engine->getKeyState(KeyDown)) {
			verticalMovement = MoveDown;
		}
		if (this->engine->getKeyState(Home)) {
			horizontalMovement = Ini;
			verticalMovement = Ini;
		}
		if (horizontalMovement != None || verticalMovement != None) {
			this->viewport->moveViewport(horizontalMovement, verticalMovement);
			this->engine->drawPortion(this->viewport->getPortionToDraw());
		}
		horizontalMovement = None;
		verticalMovement = None;
	}
	this->engine->stop();
}

util::Logger* GUIApplication::logger() {
	return util::LoggerManager::getInstance()->getLogger();
}

}

